package com.logic.modular.game.robot.match;

import com.logic.comment.util.XSThreadUtil;
import com.logic.modular.game.battle.info.base.PvpPlayerInfo;
import com.logic.modular.game.battle.info.base.PvpPlayerInfoServiceImpl;
import com.logic.modular.game.core.service.MatchServiceImpl;
import com.logic.modular.game.robot.po.RobotInfo;
import com.logic.modular.game.player.hero.service.PlayerHeroServiceImpl;
import com.comment.pojo.domain.logic.domain.PvpRanks;
import com.comment.pojo.domain.logic.domain.Player;
import com.comment.pojo.domain.logic.domain.PlayerStatus;
import com.logic.modular.game.player.info.service.PlayerServiceImpl;
import com.logic.modular.game.player.info.service.PlayerStatusServiceImpl;
import com.logic.modular.game.PvpCity;
import com.comment.pojo.domain.logic.core.PvpMatch;
import com.logic.modular.game.player.match.service.PvpCityServiceImpl;
import com.logic.modular.game.player.match.service.PvpRanksServiceImpl;
import com.comment.pojo.domain.logic.core.CoreRobotHero;
import com.comment.pojo.domain.logic.core.CoreRobotTeams;
import com.logic.modular.gameCore.match.robot.service.impl.CoreRobotHeroServiceImpl;

import com.logic.modular.gameCore.match.robot.service.impl.CoreRobotTeamsServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

/**
 * 人机匹配行为
 */
@Slf4j
@Service
public class RobotMatchActionServiceImpl {
    @Resource
    private XSThreadUtil xsThreadUtil;
    @Resource
    private PlayerHeroServiceImpl playerHeroServiceImpl;
    @Resource
    private PvpRanksServiceImpl pvpRanksServiceImpl;
    @Resource
    private PvpCityServiceImpl pvpCityServiceImpl;
    @Resource
    private PvpPlayerInfoServiceImpl pvpPlayerInfoServiceImpl;
    @Resource
    private PlayerServiceImpl playerService;
    @Resource
    private PlayerStatusServiceImpl playerStatusService;
    @Autowired
    private MatchServiceImpl matchServiceImpl;
    @Autowired
    private PlayerStatusServiceImpl playerStatusServiceImpl;

    /**
     * 人机队伍行为-(编队|出战)
     */
    public void teamsAction1(PvpMatch pvpMatch) {
        Map<Integer, CoreRobotTeams> coreRobotTeamsMap = CoreRobotTeamsServiceImpl.mapCache();
        Long matchId = pvpMatch.getId();
        try {
            Map<Long, Set<Integer>> noFormationTeamsNo = RobotInfo.obtainNoFormationTeamsNo(matchId);
            noFormationTeamsNo.forEach((robotPlayerId, noList) -> {

                for (Integer rankNo : noList) {
                    CoreRobotTeams coreRobotTeam = coreRobotTeamsMap.get(rankNo);
                    // 编 队
                    Map<Long, CoreRobotHero> longCoreRobotHeroMap = CoreRobotHeroServiceImpl.mapCache();
                    pvpRanksServiceImpl.obtainPvpRanKs(robotPlayerId);
                    pvpRanksServiceImpl.formation(
                            robotPlayerId,
                            rankNo,
                            longCoreRobotHeroMap.get(coreRobotTeam.getRobotId1()).getCoreHeroId(),
                            longCoreRobotHeroMap.get(coreRobotTeam.getRobotId2()).getCoreHeroId(),
                            longCoreRobotHeroMap.get(coreRobotTeam.getRobotId3()).getCoreHeroId()
                    );

                    // 出战
                    PvpPlayerInfo pvpPlayerInfo = pvpPlayerInfoServiceImpl.get(matchId, robotPlayerId);
                    Set<Long> currentCity = pvpPlayerInfo.getCurrentCity();
                    Long targetCity = currentCity.stream().findFirst().orElse(0L);
                    playerHeroServiceImpl.clickBattle(robotPlayerId, matchId, rankNo, targetCity);

                    // 更新人机信息
                    RobotInfo robotInfo = RobotInfo.get(robotPlayerId);
                    robotInfo.teamsStatus0.remove(rankNo);
                    robotInfo.teamsStatus1.add(rankNo);
                    robotInfo.save();
                }
            });
        } catch (Exception e) {
            log.error("", e);
        }
    }

    /**
     * 人机队伍行为-(招兵|攻打城池)
     */
    public void robotTeamsAttackHeat() {
        Map<Integer, CoreRobotTeams> coreRobotTeamsMap = CoreRobotTeamsServiceImpl.mapCache();
        xsThreadUtil.scheduledExecutorService().scheduleAtFixedRate(() -> {
            Set<Long> longs = RobotInfo.obtainNeedRobotTeamsAttackMatchId();
            // log.info("人机队伍行为-(招兵|攻打城池),size:{}", longs.size());
            for (Long matchId : longs) {
                try {
                    Map<Long, Set<Integer>> noBattleTeamsNo =
                            RobotInfo.obtainNoBattleTeamsNo(matchId);
                    noBattleTeamsNo.forEach((robotPlayerId, noBattleList) -> {
                        RobotInfo robotInfo = RobotInfo.get(robotPlayerId);
                        PlayerStatus playerStatus = playerStatusServiceImpl.get(robotPlayerId);
                        if (playerStatus == null || playerStatus.getCurrentMatchId() == null || playerStatus.getCurrentMatchId() < 1) {
                            return;
                        }

                        // 查看上次攻击的时间
                        Long lastAttackTime = robotInfo.getLastAttackTime();
                        long nextAttackTime = lastAttackTime + 1000 * 60 * 5;
                        if (System.currentTimeMillis() < nextAttackTime) {
                            log.info("比赛:{},人机:{},未到下次攻击时间,下次攻击时间:{}", matchId, robotPlayerId, new Date(nextAttackTime));
                            return;
                        }
                        // 转list 获取随机队伍
                        List<Integer> list = new ArrayList<>(noBattleList);
                        Integer randomTeamsNo = list.get(new Random().nextInt(list.size()));

                        // 获取配队信息
                        CoreRobotTeams coreRobotTeam = coreRobotTeamsMap.get(randomTeamsNo);
                        Map<Long, Long> longLongMap = coreRobotTeam.obtainRobotIdsAndForce();
                        Map<Long, CoreRobotHero> longCoreRobotHeroMap = CoreRobotHeroServiceImpl.mapCache();

                        try {
                            longLongMap.forEach((robotId, force) -> {
                                CoreRobotHero cache = longCoreRobotHeroMap.get(robotId);
                                Long coreHeroId = cache.getCoreHeroId();
                                playerHeroServiceImpl.buBingNoPay(robotPlayerId, coreHeroId, force);
                            });
                        } catch (Exception e) {
                            log.info("人机:{},补兵行为失败", robotPlayerId, e);
                            return;
                        }

                        // 获取可攻打城池
                        List<PvpCity> pvpCities = pvpCityServiceImpl.obtainCanAttackTheCityWalls(robotPlayerId, matchId);
                        // 随机一个
                        int size = pvpCities.size();
                        if (size == 0) {
                            log.info("人机:{},未找到可攻打的城池", robotPlayerId);
                            return;
                        }

                        PvpCity remove = pvpCities.remove(new Random().nextInt(size));
                        // 进行攻打
                        PvpRanks ranks = pvpRanksServiceImpl.select(robotPlayerId, randomTeamsNo);
                        if (ranks.getStatus() == 1) {
                            pvpRanksServiceImpl.tryAttackCityNoPap(
                                    robotPlayerId, matchId, (randomTeamsNo), remove.getCoreCityId(),
                                    null);
                            // 更新人机信息
                            robotInfo.teamsStatus1.remove(randomTeamsNo);
                            robotInfo.teamsStatus2.add(randomTeamsNo);
                            robotInfo.setLastAttackTime(System.currentTimeMillis());
                            robotInfo.save();
                        }
                    });
                } catch (Exception e) {
                    log.error("", e);
                }
            }
        }, 1, 30, TimeUnit.SECONDS);
    }

    /**
     * 人机加入匹配行为
     */
    public PvpMatch humanMachineJoiningMatchingBehavior(PvpMatch pvpMatch) {
        int robotJoinTime = 1;
        ScheduledFuture<?> future = xsThreadUtil.scheduledExecutorService().schedule(() -> {
            try {
                int num = pvpMatch.getStartThreshold() - 1;
                if (num > 0) {
                    List<Player> players = playerService.obtainFreeRobot(num);
                    for (Player player : players) {
                        Long uid = player.getUid();
                        pvpMatch.playerCount.add(uid);
                        pvpMatch.playerIds.add(uid);
                        playerStatusService.updateMatch(uid, pvpMatch.getId());

                        // 尝试初始人机队伍
                        pvpRanksServiceImpl.obtainPvpRanKs(uid);

                        RobotInfo robotInfo = new RobotInfo(uid);
                        robotInfo.setMatchId(pvpMatch.getId());
                        robotInfo.save();
                    }
                }
            } catch (Exception e) {
                log.error("对局机器人生成任务异常", e);
            }
        }, robotJoinTime, TimeUnit.MILLISECONDS);

        // 等待任务完成
        try {
            future.get(); // 这里会阻塞，直到任务完成
        } catch (InterruptedException | ExecutionException e) {
            log.error("等待任务完成时发生异常", e);
        }

        return pvpMatch;
    }

    // /**
    //  * 快速匹配机器人任务  10分钟一次
    //  */
    // @SuppressWarnings("unchecked")
    // @Scheduled(cron = "0 0/10 * * * ?")
    // public void quickMatchRobotTask(){
    //     // 获取所有匹配池
    //     MapUtil<Object, Object> allMatchPool = PvpMatch.getAllMatchPool();
    //     allMatchPool.forEach((k, v)->{
    //         String[] split = k.toString().split("-");
    //         Long mapId = Long.valueOf(split[1]);
    //         Integer type = Integer.valueOf(split[2]);
    //         Integer startThreshold = Integer.valueOf(split[3]);
    //         Set<Long> playerIds = (Set<Long>) v;
    //         // 获取凑够人数需要多少
    //         int num = startThreshold - playerIds.size();
    //         if (num > 0) {
    //             List<Player> players = playerService.obtainFreeRobot(num);
    //             for (Player player : players) {
    //                 Long uid = player.getUid();
    //                 PvpMatch realPersonMatchQuick = matchServiceImpl.realPersonMatchQuick(uid, mapId, startThreshold);
    //                 RobotInfo robotInfo = new RobotInfo(uid);
    //                 robotInfo.setMatchId(realPersonMatchQuick.getId());
    //                 robotInfo.save();
    //             }
    //         }
    //
    //     });
    // }

}
